# -*- coding:utf-8 -*-
import pygame
from pygame import surface
import sys,os
import random
from Framework import Level, Snake, Food, Logic


class SoundManager(object):
    def __init__(self):
        super().__init__()
        mixer = pygame.mixer
        mixer.init( 44100 )
        self.music = mixer.music
        ap = os.path.abspath('.')
        filename = ap+'/asset/bgfx.wav'
        self.music.load( filename )
        self.music.set_volume( 0.5 )
        self.score_add= pygame.mixer.Sound(ap+'/asset/score_add.wav')
        self.score_dec= pygame.mixer.Sound(ap+'/asset/score_dec.wav')

    def play_bg(self):
        self.music.play(100000)
    def play_score_add(self):
        self.score_add.play()
    def play_score_dec(self):
        self.score_dec.play()



# //PORT:native code
class LevelRender(object):
    def __init__(self, display: surface, level: Level):
        super().__init__()
        self.level = level
        self.display = display
        self.tick = 0
        self.flash = True
        self.flash_2x = True
        self.BRICK_COLOR = (136, 0, 21)
        self.FOOD_COLOR_0 = (255, 255, 21)
        self.FOOD_COLOR_1 = (255, 10, 21)
        self.FOOD_COLOR_2 = (10, 255, 21)
        self.SNAKE_HEAD = (128, 0, 128)
        self.SNAKE_COLOR = (255, 0, 255)

        ap = os.path.abspath('.')
        self.asset_bg = pygame.image.load(ap+'/asset/bg.png')
        self.asset_snake_head = pygame.image.load(ap+'/asset./sh.png')
        self.asset_snake_body = pygame.image.load(ap+'/asset./sb.png')
        self.asset_snake_tail = pygame.image.load(ap+'/asset./st.png')
        self.asset_snake_corner = pygame.image.load(ap+'/asset./sc.png')

        self.asset_food_1 = pygame.image.load(ap+'/asset./m1.png')
        self.asset_food_2 = pygame.image.load(ap+'/asset./m2.png')
        self.asset_food_3 = pygame.image.load(ap+'/asset./m3.png')

        self.asset_fence_corner = pygame.image.load(ap+'/asset./fc.png')
        self.asset_fence_line = pygame.image.load(ap+'/asset./fs.png')

    def show_text(self, pos, text, color, font_bold=False, font_size=60, font_italic=False):
        # 获取系统字体，并设置文字大小
        cur_font = pygame.font.SysFont("宋体", font_size)
        # 设置是否加粗属性
        cur_font.set_bold(font_bold)
        # 设置是否斜体属性
        cur_font.set_italic(font_italic)
        # 设置文字内容
        text_fmt = cur_font.render(text, 1, color)
        # 绘制文字
        self.display.blit(text_fmt, pos)

    def draw_raw_block(self, x, y, color):
        w = self.level.BLOCK_WIDTH
        rect = pygame.Rect(x * w, y * w, w, w)
        pygame.draw.rect(self.display, color, rect, 0)

    def draw_img(self, x, y, img,rotate):
        d_img = img
        if rotate != 0 :
            d_img = pygame.transform.rotate(img,rotate)
        w = self.level.BLOCK_WIDTH
        _x = (x + 1) * w
        _y = (y + 1) * w
        self.display.blit(d_img,(_x,_y))

    def draw_obj(self, x, y, color):
        self.draw_raw_block(x+1, y+1, color)

    def render(self):
        self.tick += 1
        if self.tick % 20 == 0:
            if self.flash:
                self.flash = False
            else:
                self.flash = True
        if self.tick % 10 == 0:
            if self.flash_2x:
                self.flash_2x = False
            else:
                self.flash_2x = True

        #loop_var clear
        self.snake_speed_up = False
        self.snake_mabi = False

        #0 - clean
        self.display.fill((255, 255, 255))

        # 1 - render food
        for food in self.level.food_list:
            if not food.been_eated:
                if not food.almost_change() or self.flash:
                    img = self.asset_food_1
                    if food.type == 1:
                        img = self.asset_food_2
                    elif food.type == 2:
                        img = self.asset_food_3
                    self.draw_img(food.location[0],food.location[1],img,0)

        # 2 - render snake
        for snake in self.level.snakes:
            if snake.speed > 16 :
                self.snake_speed_up = True
            if snake.sfx_mabi_counter > 0:
                self.snake_mabi = True
            last_body_rotation = 0
            for i in range(0, snake.l):
                #snake body draw
                draw = True
                img = self.asset_snake_body
                rotation = 0
                direction = snake.body[i][2]
                turn_value = snake.body[i][3]

                body_rotate = 0
                if direction == 'R':
                    body_rotate = 270
                elif direction == 'D':
                    body_rotate = 180
                elif direction == 'L':
                    body_rotate = 90
                rotation = body_rotate

                corner_rotate  = 0
                if turn_value == 'T_0':
                    img = self.asset_snake_corner
                    corner_rotate = 0
                elif turn_value == 'T_90':
                    img = self.asset_snake_corner
                    corner_rotate = 90
                elif turn_value == 'T_180':
                    img = self.asset_snake_corner
                    corner_rotate = 180
                elif turn_value == 'T_270':
                    img = self.asset_snake_corner
                    corner_rotate = 270
                #over ride
                if turn_value != '':
                    rotation = corner_rotate

                if i == 0:
                    img = self.asset_snake_head
                if i == snake.l - 1:
                    img = self.asset_snake_tail
                    #tail use body rotation + corner rotation
                    #if corner_rotate > 0:
                    rotation = last_body_rotation
                if  self.level.game_end:
                    draw =  self.flash
                elif self.level.sfx_time_counter > 0 and snake.cut_body > 0:
                    draw = (i < snake.cut_body or self.flash_2x)
                elif snake.sfx_mabi_counter > 0:
                    draw = self.flash_2x
                if  draw:
                    self.draw_img(snake.body[i][0],snake.body[i][1],img,rotation)
                last_body_rotation = body_rotate

        # 3 - render fence
        for i in range(0, self.level.size[0]+2):
            #hor
            if i == 0:
                self.draw_img(i - 1,0,self.asset_fence_corner,90)
                self.draw_img(i - 1,self.level.size[1],self.asset_fence_corner,180)
                continue
            if i == self.level.size[0] + 1:
                self.draw_img(i - 1,0,self.asset_fence_corner,0)
                self.draw_img(i - 1,self.level.size[1],self.asset_fence_corner,270)
                continue
            self.draw_img(i - 1,0,self.asset_fence_line,0)
            self.draw_img(i - 1,self.level.size[1],self.asset_fence_line,0)
        for i in range(1, self.level.size[1]):
            #vetc
            self.draw_img(-1, i,self.asset_fence_line,90)
            self.draw_img(self.level.size[0], i,self.asset_fence_line,90)

        # 4 text
        if not self.level.game_end or self.flash_2x:
            self.show_text((self.level.BLOCK_WIDTH, 15 + self.level.BLOCK_WIDTH),
                           'Score:%d' % self.level.score, (227, 100, 90), True, 25)
        if self.level.game_end:
            l = self.level.display_size[0] / 2 - 150
            t = self.level.display_size[1] / 2 - 60
            if self.flash:
                self.show_text((l, t), 'Wasted!', (227, 100, 90), True, 100)
            self.show_text((l+70, t+70), 'press SPACE to reset',
                           (227, 100, 90), True, 20)

        if self.snake_speed_up:
            self.show_text((self.level.BLOCK_WIDTH, 15 +  self.level.BLOCK_WIDTH * 2),
                           'Speed Up!!!', (227, 100, 90), True, 25)

        if self.snake_mabi:
            self.show_text((self.level.BLOCK_WIDTH, 15 +  self.level.BLOCK_WIDTH * 2),
                           'Slow Down!!!', (227, 100, 90), True, 25)

def game_entry():
    pygame.init()
    # vars
    level = Level()
    game_logic = Logic(level)
    display = pygame.display.set_mode(level.display_size)
    clock = pygame.time.Clock()
    level_render = LevelRender(display, level)
    sound = SoundManager()
    # setup
    pygame.display.set_caption(level.title)
    sound.play_bg()

    old_score = 0
    # loop
    while True:
        for event in pygame.event.get():
            if pygame.QUIT == event.type:
                sys.exit()
            if pygame.KEYDOWN == event.type:
                if pygame.K_LEFT == event.key:
                    game_logic.update_player_control(0, 'L')
                if pygame.K_RIGHT == event.key:
                    game_logic.update_player_control(0, 'R')
                if pygame.K_UP == event.key:
                    game_logic.update_player_control(0, 'U')
                if pygame.K_DOWN == event.key:
                    game_logic.update_player_control(0, 'D')
                if pygame.K_SPACE == event.key:
                    if level.game_end:
                        level.reset()
                        old_score = 0

        if not level.game_end:
            game_logic.update()
            if level.score > old_score:
                sound.play_score_add()
            if level.score < old_score:
                sound.play_score_dec()
            old_score = level.score

        level_render.render()
        pygame.display.update()
        # 60 Fps max
        clock.tick(60)


if __name__ == '__main__':
    game_entry()
